/*
 * gc.c
 *
 *  Created on: 2009-12-3
 *      Author: Bearice
 */
#include <vm_exec.h>
#include <gc.h>
#include <stdlib.h>
#include <memory.h>
struct avm_gcblock* pool;
uint32 gc_init(uint32 size){
	pool = malloc(sizeof(struct avm_gcblock));
	memset(pool,0,sizeof(struct avm_gcblock));
        pool->next_free = pool->pool = malloc(sizeof(void*)*size);
        pool->size = size;
        return size;
}
struct avm_object* gc_alloc() {
	pool->alloc++;
	struct avm_object* ret = *pool->next_free = malloc(sizeof(struct avm_object));
	memset(ret,0,sizeof(struct avm_object));
	ret->hashcode  = pool->next_free;
	while (pool->next_free && pool->next_free < pool->pool + pool->size) {
		pool->next_free++;
	}
	return ret;
}
uint32 gc_free(struct avm_object* obj) {
	if (gc_declref(obj)==0) {
		if (obj->tag == TAG_PAIR) {
			if (obj->val.pair.left)
				gc_free(obj->val.pair.left);
			if (obj->val.pair.right)
				gc_free(obj->val.pair.left);
		}
		pool->alloc--;
		*obj->hashcode=NULL;
		if(pool->next_free>obj->hashcode)pool->next_free = obj->hashcode;
		free(obj);
	}
	return 0;
}
uint32 gc_inclref(struct avm_object* obj) {
	return obj!=NULL&&obj!=-1?++(obj->ref):-1;
}
uint32 gc_declref(struct avm_object* obj) {
	return obj!=NULL&&obj!=-1?--(obj->ref):-1;
}
